﻿using System.Collections.Generic;

namespace NamedBinaryTag
{
	/// <summary>
	/// Represents a Tag containing a list of Tag with names.
	/// </summary>
	public sealed class TagCompound : NamedTag
	{
		/// <summary>
		/// Obtains the collection of inner Tags.
		/// </summary>
		public System.Collections.ObjectModel.ObservableCollection<ITag> Items { get; private set; }

		public override byte TagType
		{
			get { return 10; }
		}

		/// <summary>
		/// Obtains the Tag with the specified name.
		/// </summary>
		/// <param name="name">The name to search for.</param>
		/// <returns>The found tag or <code>null</code> if none.</returns>
		public ITag this[string name]
		{
			get
			{
				foreach (ITag item in Items)
				{
					if (item.Name == name)
						return item;
				}
				return null;
			}
		}

		public TagCompound()
		{
			Items = new System.Collections.ObjectModel.ObservableCollection<ITag>();
		}

		public override void Read(System.IO.BinaryReader input, bool ignoreName)
		{
			base.Read(input, ignoreName);
			IList<ITag> items = new List<ITag>();
			TagByte type = new TagByte();
			ITag element = null;
			while (true)
			{
				type.Read(input, true);
				element = TagFactory.CreateTag(type.Value);
				if (element is TagEnd)
					break;
				element.Read(input);
				items.Add(element);
			}
			Items.Clear();
			foreach (ITag item in items)
				Items.Add(item);
		}

		public override void Write(System.IO.BinaryWriter output, bool ignoreName)
		{
			base.Write(output, ignoreName);
			TagByte type = new TagByte();
			foreach (ITag element in Items)
			{
				type.Value = element.TagType;
				type.Write(output, true);
				element.Write(output);
			}
			TagEnd end = new TagEnd();
			type.Value = end.TagType;
			type.Write(output, true);
		}

		public override string ToString()
		{
			return string.Format("TagCompound {{ Name = \"{0}\", Count = {1} }}", Name, Items.Count);
		}
	}
}
